package com.yy.util;

/**
 * 小端位操作工具
 */
public final class BitConverter {
    private BitConverter() {

    }

    /**
     * 从byte数组中获取short，低字节在前
     *
     * @param value
     * @param startIndex
     * @return
     */
    public static short toShort(byte[] value, int startIndex) {
        short result = 0;


        if (startIndex >= 0 && startIndex + 1 < value.length) {
            result = value[startIndex + 1];
            result = (short) (result << 8);
            result |= (0x00FF & (short) value[startIndex]);
        }

        return result;
    }

    /**
     * 从byte数组中获取char，低字节在前
     *
     * @param value
     * @param startIndex
     * @return
     */
    public static char toChar(byte[] value, int startIndex) {
        char result = 0;

        if (startIndex >= 0 && startIndex + 1 < value.length) {
            result = (char) (value[startIndex + 1]);
            result = (char) (result << 8);
            result |= (0x00FF & (char) value[startIndex]);
        }

        return result;
    }

    public static byte toByte(byte[] value, int startIndex) {
        byte result = 0;

        if (startIndex >= 0 && startIndex < value.length) {
            result = value[startIndex];
        }

        return result;
    }

    /**
     * 从byte数组中获取int,低字节在前
     *
     * @param value
     * @param startIndex
     * @return
     */
    public static int toInt(byte[] value, int startIndex) {
        int result = 0;

        if (startIndex >= 0 && startIndex + 3 < value.length) {
            result = value[startIndex + 3];
            result = (int) (result << 8);
            result |= (0x000000FF & (int) value[startIndex + 2]);
            result = (int) (result << 8);
            result |= (0x000000FF & (int) value[startIndex + 1]);
            result = (int) (result << 8);
            result |= (0x000000FF & (int) value[startIndex]);
        }

        return result;
    }

    /**
     * 取2字节 0~65535 Unsigned short 类型
     *
     * @param value
     * @param startIndex
     * @return int
     */
    public static int toUnsignedInt(byte[] value, int startIndex) {
        int result = 0;
        if (startIndex >= 0 && startIndex + 1 < value.length) {
            result |= (0x000000FF & (int) value[startIndex + 1]);
            result = (int) (result << 8);
            result |= (0x000000FF & (int) value[startIndex]);
        }

        return result;
    }

    /**
     * 从byte数组中获取long,低字节在前
     *
     * @param value
     * @param startIndex
     * @return
     */
    public static long toLong(byte[] value, int startIndex) {
        long result = 0;

        if (startIndex >= 0 && startIndex + 7 < value.length) {
            result = value[startIndex + 7];
            result = (long) (result << 8);
            result |= (0x00000000000000FF & (long) value[startIndex + 6]);
            result = (long) (result << 8);
            result |= (0x00000000000000FF & (long) value[startIndex + 5]);
            result = (long) (result << 8);
            result |= (0x00000000000000FF & (long) value[startIndex + 4]);
            result = (long) (result << 8);
            result |= (0x00000000000000FF & (long) value[startIndex + 3]);
            result = (long) (result << 8);
            result |= (0x00000000000000FF & (long) value[startIndex + 2]);
            result = (long) (result << 8);
            result |= (0x00000000000000FF & (long) value[startIndex + 1]);
            result = (long) (result << 8);
            result |= (0x00000000000000FF & (long) value[startIndex + 0]);
        }

        return result;
    }

    /**
     * 获取short类型的字节，低字节在前
     *
     * @param value
     * @return byteArray
     */
    public static byte[] getBytes(short value) {
        byte[] byteArray = new byte[2];
        byteArray[0] = (byte) (value & 0x00FF);
        byteArray[1] = (byte) ((value & 0xFF00) >> 8);

        return byteArray;
    }

    /**
     * 获取char类型的字节，低字节在前
     *
     * @param value
     * @return byteArray
     */
    public static byte[] getBytes(char value) {
        byte[] byteArray = new byte[2];
        byteArray[0] = (byte) (value & 0x00FF);
        byteArray[1] = (byte) ((value & 0xFF00) >> 8);

        return byteArray;
    }

    /**
     * 获取char类型的字节，低字节在前
     *
     * @param value
     * @return byteArray
     */
    public static byte[] getBigBytes(char value) {
        byte[] byteArray = new byte[2];
        byteArray[1] = (byte) (value & 0x00FF);
        byteArray[0] = (byte) ((value & 0xFF00) >> 8);

        return byteArray;
    }

    /**
     * 获取int类型的字节，低字节在前
     *
     * @param value
     * @return
     */
    public static byte[] getBytes(int value) {
        byte[] byteArray = new byte[4];
        byteArray[0] = (byte) (value & 0x000000FF);
        byteArray[1] = (byte) ((value & 0x0000FF00) >> 8);
        byteArray[2] = (byte) ((value & 0x00FF0000) >> 16);
        byteArray[3] = (byte) ((value & 0xFF000000) >> 24);

        return byteArray;
    }

    /**
     * 将byteBit与 bit做一次与运算，然后用displacement位移得到结果
     *
     * @param byteBit      传入的byte原字节集
     * @param bit          与运算对象
     * @param displacement 位移几位
     * @return
     */
    public static byte andOperationAfterToRightDisplacement(byte byteBit, byte bit, int displacement) {
        return (byte) ((byteBit & bit) >> displacement);
    }

    /**
     * 将byteBit与 bit做一次与运算，然后用displacement位移得到结果
     *
     * @param byteBit      传入的byte原字节集
     * @param bit          与运算对象
     * @param displacement 位移几位
     * @return
     */
    public static int andOperationAfterToRightDisplacement(int byteBit, int bit, int displacement) {
        return ((byteBit & bit) >> displacement);
    }

    /**
     * 将一个int数字转换为二进制的字符串形式。
     *
     * @param num    需要转换的int类型数据
     * @param digits 要转换的二进制位数，位数不足则在前面补0
     * @return 二进制的字符串形式
     */
    public static String toBinary(int num, int digits) {
        String cover = Integer.toBinaryString(1 << digits).substring(1);
        String s = Integer.toBinaryString(num);
        return s.length() < digits ? cover.substring(s.length()) + s : s;
    }
}
